﻿/*
 * @author Lee 
 * Time: 20180403 
 * Abstract: SharePoint API的二次封装
 */

using System;
using Microsoft.SharePoint;

namespace SharePointHelper.DLL.SSOM
{
	public class Wiki
	{
        /// <summary>
        ///  在wiki content area插入 HTML 的方式
        /// </summary>
        public enum InsertionLocation
		{
			Prepend,
			Append,
			Replace,
		}

        #region 获取wiki content area的内部HTML. 不包括outer table and div tags
        /// <summary>
        /// 获取wiki content area的内部HTML. 不包括outer table and div tags
        /// </summary>
        /// <param name="wiki"></param>
        /// <param name="tableCellIndex">如果内容区域有多个表单元格，则使用此选项选择特定的td
        /// 从1开始</param>
        /// <returns></returns>
        public static string GetHtml(SPListItem wiki, byte? tableCellIndex)
		{
			string o = null;
			string wikiCompleteHtml = null;
			try
			{
				// 初始化
				if (wiki == null) { throw new Exception("wiki item passed is null"); }
				if (wiki[SPBuiltInFieldId.WikiField] != null)
				{
					wikiCompleteHtml = wiki[SPBuiltInFieldId.WikiField].ToString();
				}
				if (tableCellIndex == null || tableCellIndex == 0) { tableCellIndex = 1; }


				if (!string.IsNullOrEmpty(wikiCompleteHtml))
				{
                    // 将HTML转换成xml
                    // <?xml version="1.0" encoding="ISO-8859-1"?>
                    System.Xml.XmlDocument wikiXml = new System.Xml.XmlDocument();
					wikiXml.LoadXml(wikiCompleteHtml);

					// 获取所有 table cells
					System.Xml.XmlNodeList tableCells = wikiXml.SelectNodes("/div/table/tbody/tr/td");
					if (tableCells == null || tableCells.Count == 0) { throw new Exception("Failed to find any table cells"); }
					if (tableCells.Count < tableCellIndex) { throw new Exception("Invalid column: " + tableCellIndex + ". Max number of tabl cells returned: " + tableCells.Count); }

					// 获取 column innerHtml
					byte index = 1;
					foreach (System.Xml.XmlNode n in tableCells)
					{
						if (index == (byte)tableCellIndex)
						{
							o = n.SelectSingleNode("div/div").InnerXml;
						}
						index++;
					}
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("drtuygiffdyseesataseteast", ex, "wiki complete html: " + wikiCompleteHtml);
				o = null;
			}
			return o;
		}
        #endregion

        #region 在一个wiki content area添加 html , 放置在现有的html容器的 div/table tags中
        /// <summary>
        /// 在一个wiki content area添加 html , 放置在现有的html容器的 div/table tags中
        /// </summary>
        /// <param name="wiki"></param>
        /// <param name="htmlToAdd"></param>
        /// <param name="whereToInsert"></param>
        /// <param name="tableCellIndex"></param>
        /// <returns></returns>
        public static bool AddHtml(SPListItem wiki, string htmlToAdd, InsertionLocation whereToInsert, byte? tableCellIndex, bool isSave)
		{
			bool isSuccess = false;
			string wikiCompleteHtml = null;
			try
			{
				// 初始化
				if (wiki == null) { throw new Exception("wiki item passed is null"); }
				if (wiki[SPBuiltInFieldId.WikiField] != null)
				{
					wikiCompleteHtml = wiki[SPBuiltInFieldId.WikiField].ToString();
				}
				if (tableCellIndex == null || tableCellIndex == 0) { tableCellIndex = 1; }


				if (string.IsNullOrEmpty(wikiCompleteHtml))
				{
                    // 当前是空的，没有外部HTML。只需添加HTML
                    wiki[SPBuiltInFieldId.WikiField] = htmlToAdd;
				}
				else
				{
                    // 将HTML转换成xml
                    // <?xml version="1.0" encoding="ISO-8859-1"?>
                    System.Xml.XmlDocument wikiXml = new System.Xml.XmlDocument();
					wikiXml.LoadXml(wikiCompleteHtml);

					// 获取所有 table cells
					System.Xml.XmlNodeList tableCells = wikiXml.SelectNodes("/div/table/tbody/tr/td");
					if (tableCells == null || tableCells.Count == 0) { throw new Exception("Failed to find any table cells"); }
					if (tableCells.Count < tableCellIndex) { throw new Exception("Invalid column: " + tableCellIndex + ". Max number of tabl cells returned: " + tableCells.Count); }

					// 获取 column innerHtml
					byte index = 1;
					bool isMatch = false;
					foreach (System.Xml.XmlNode n in tableCells)
					{
						if (index == (byte)tableCellIndex)
						{
							isMatch = true;
							if (whereToInsert == InsertionLocation.Prepend)
							{
								n.SelectSingleNode("div/div").InnerXml = htmlToAdd + n.SelectSingleNode("div/div").InnerXml;
							}
							else if (whereToInsert == InsertionLocation.Replace)
							{
								n.SelectSingleNode("div/div").InnerXml = htmlToAdd;
							}
							else if (whereToInsert == InsertionLocation.Append)
							{
								n.SelectSingleNode("div/div").InnerXml += htmlToAdd;
							}
						}
						index++;
					}

					if (!isMatch) { throw new Exception("Failed to find table cell for column: " + tableCellIndex); }

                    // 通过XML回到wiki item
                    wiki[SPBuiltInFieldId.WikiField] = wikiXml.OuterXml;
				}

				// 报错
				if (isSave) { wiki.Update(); }

				isSuccess = true;
			}
			catch (Exception ex)
			{
				Log.WriteError("zdstguftudrsdrstrd6dfdx", ex, "wiki complete html: " + wikiCompleteHtml);
				isSuccess = false;
			}
			return isSuccess;
		}
        #endregion

        #region 替换 element contents, 比如一个 div with unique id, 替换这个div里面的所有innterHtml
        /// <summary>
        /// 替换 element contents, 比如一个 div with unique id, 替换这个div里面的所有innterHtml
        /// </summary>
        /// <param name="wiki"></param>
        /// <param name="elementName">tag name, 比如 div or p</param>
        /// <param name="elementIdToReplace">这个标签的unique id </param>
        /// <param name="elementInstanceToReplace">如果NULL或0，将替换所有，如果2，然后用这个方法参数中的ID替换第二个元素实例。</param>
        /// <param name="htmlToReplaceWith">新的 innerHtml</param>
        /// <returns></returns>
        public static bool ReplaceElementContent(SPListItem wiki, string elementName, string elementIdToReplace, string htmlToReplaceWith, bool isSave)
		{
			bool isSuccess = false;
			string wikiCompleteHtml = null;
			try
			{
				// 初始化
				if (wiki == null) { throw new Exception("wiki item passed is null"); }
				if (wiki[SPBuiltInFieldId.WikiField] != null)
				{
					wikiCompleteHtml = wiki[SPBuiltInFieldId.WikiField].ToString();
				}
				if (string.IsNullOrEmpty(elementName)) { throw new Exception("elementName passed is null"); }


				int numberElementsAffected = 0;
				wiki[SPBuiltInFieldId.WikiField] = Xml.ReplaceElements(wiki[SPBuiltInFieldId.WikiField].ToString(), 
					htmlToReplaceWith, elementName, elementIdToReplace, false, ref numberElementsAffected);
				
				// 是否保存?
				if (isSave) { wiki.Update(); }

				isSuccess = true;
			}
			catch (Exception ex)
			{
				Log.WriteError("sryestddGGaer44", ex, "wiki complete html: " + wikiCompleteHtml);
				isSuccess = false;
			}
			return isSuccess;
		}
        #endregion

        #region 根据 name 和 id 删除element(s)
        /// <summary>
        /// 根据 name 和 id 删除element(s)
        /// </summary>
        /// <param name="wiki"></param>
        /// <param name="elementName">element name, 比如 div, p, or table</param>
        /// <param name="elementId">id="" attribute</param>
        /// <param name="elementInstance"></param>
        /// <returns></returns>
        public static bool DeleteElements(SPListItem wiki, string elementName, string elementId, byte? elementInstance, bool isSave)
		{
			bool isSuccess = false;
			string wikiCompleteHtml = null;
			try
			{
				// 初始化
				if (wiki == null) { throw new Exception("wiki item passed is null"); }
				if (wiki[SPBuiltInFieldId.WikiField] != null)
				{
					wikiCompleteHtml = wiki[SPBuiltInFieldId.WikiField].ToString();
				}
				if (string.IsNullOrEmpty(elementId)) { throw new Exception("elementId passed is null"); }
				if (string.IsNullOrEmpty(elementName)) { throw new Exception("elementName passed is null"); }
				if (elementInstance == null) { elementInstance = 0; }


                // 将HTML转换成xml
                // <?xml version="1.0" encoding="ISO-8859-1"?>
                System.Xml.XmlDocument wikiXml = new System.Xml.XmlDocument();
				wikiXml.LoadXml(wikiCompleteHtml);

				// 获取所有 divs with id passed
				System.Xml.XmlNodeList elements = wikiXml.SelectNodes("//" + elementName + "[@id='" + elementId + "']");
				if (elements != null && elements.Count > 0)
				{
					for (byte i = 0; i < elements.Count; i++)
					{
						if (elementInstance == 0 || ((elementInstance - 1) == i))
						{
							elements[i].ParentNode.RemoveChild(elements[i]);
						}
					}

					wiki[SPBuiltInFieldId.WikiField] = wikiXml.OuterXml;
				}

				if (isSave) { wiki.Update(); }

				isSuccess = true;
			}
			catch (Exception ex)
			{
				Log.WriteError("5e6ujdsrer4e54r", ex, "wiki complete html: " + wikiCompleteHtml);
				isSuccess = false;
			}
			return isSuccess;
		}
        #endregion

        #region 移除所有 inner html, 保留现有文本布局
        /// <summary>
        /// 移除所有 inner html, 保留现有文本布局
        /// </summary>
        /// <param name="wiki"></param>
        /// <returns></returns>
        public static bool DeleteHtml(SPListItem wiki, bool isSave)
		{
			bool isSuccess = false;
			string wikiCompleteHtml = null;
			try
			{
				// 初始化
				if (wiki == null) { throw new Exception("wiki item passed is null"); }
				if (wiki[SPBuiltInFieldId.WikiField] != null)
				{
					wikiCompleteHtml = wiki[SPBuiltInFieldId.WikiField].ToString();
				}


				if (!string.IsNullOrEmpty(wikiCompleteHtml))
				{
                    // 将HTML转换成xml
                    // <?xml version="1.0" encoding="ISO-8859-1"?>
                    System.Xml.XmlDocument wikiXml = new System.Xml.XmlDocument();
					wikiXml.LoadXml(wikiCompleteHtml);

					// 获取所有 table cells
					System.Xml.XmlNodeList tableCells = wikiXml.SelectNodes("/div/table/tbody/tr/td");
					if (tableCells == null || tableCells.Count == 0) { throw new Exception("Failed to find any table cells"); }

					foreach (System.Xml.XmlNode n in tableCells)
					{
						n.SelectSingleNode("div/div").InnerXml = string.Empty;
					}

					wiki[SPBuiltInFieldId.WikiField] = wikiXml.OuterXml;
				}

				if (isSave) { wiki.Update(); }
 
				isSuccess = true;
			}
			catch (Exception ex)
			{
				Log.WriteError("r54ythrsdrsdsr5r", ex, "wiki complete html: " + wikiCompleteHtml);
				isSuccess = false;
			}
			return isSuccess;
		}
        #endregion

    }
}
